package cn.yuitstyle.license.starter.util;

import cn.hutool.core.date.DateUtil;
import cn.yuitstyle.license.starter.manage.CustomLicenseManager;
import cn.yuitstyle.license.starter.manage.LicenseManagerHolder;
import cn.yuitstyle.license.starter.model.CustomKeyStoreParam;
import cn.yuitstyle.license.starter.model.LicenseVerifyParam;
import de.schlichtherle.license.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.ClassPathResource;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.prefs.Preferences;

/**
 * 项目启动校验Lisence
 */
@Slf4j
public class LicenseVerify {


    /**
     * 安装License证书
     */
    public synchronized LicenseContent install(LicenseVerifyParam param, ConfigurableApplicationContext context) {
        LicenseContent result = null;
        //1. 安装证书
        try {

            LicenseParam licenseParam = initLicenseParam(param);
            LicenseManager licenseManager = LicenseManagerHolder.getLicenseManager(licenseParam);

            result = licenseManager.install(new File(param.getLicensePath()));
            //  2.校验证书信息
            CustomLicenseManager cl = new CustomLicenseManager();
            cl.validateCreate(result);
            cl.validate(result);

            log.info(MessageFormat.format("{0} 证书安装成功，证书有效期：{1} - {2}",
                    result.getInfo(), DateUtil.formatDateTime(result.getNotBefore()), DateUtil.formatDateTime(result.getNotAfter())));
        } catch (LicenseContentException e) {
            if (e.getMessage().equals("exc.licenseHasExpired")) {
                log.error("证书已过期");
            } else {
                log.error(e.getMessage());
            }
        } catch (Exception e) {
            log.error("证书安装失败！", e);
            context.close();
            return null;
        }

        return result;
    }


    /**
     * 校验License证书
     */
    public boolean verify() {
        LicenseManager licenseManager = LicenseManagerHolder.getLicenseManager(null);
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        //2. 校验证书
        try {
            LicenseContent licenseContent = licenseManager.verify();

            if (checkLicenseVerify(licenseContent.getNotBefore(), licenseContent.getNotAfter())) {
                return false;
            }

            log.info(MessageFormat.format("证书校验通过，证书有效期：{0} - {1}",
                    format.format(licenseContent.getNotBefore()), format.format(licenseContent.getNotAfter())));
            return true;
        } catch (Exception e) {
            log.error("证书校验失败！", e);
            return false;
        }
    }

    /**
     * 校验证书日期是否有效
     */
    private boolean checkLicenseVerify(Date startDate, Date endDate) {
        Date now = new Date();
        if (endDate.before(now)) {
            log.info(MessageFormat.format("证书校验失败，证书有效期：{0} - {1}，当前时间为 {2}",
                    DateUtil.formatDateTime(startDate), DateUtil.formatDateTime(endDate), DateUtil.formatDateTime(now)));
            return true;
        }
        return false;
    }

    /**
     * 初始化证书生成参数
     */
    private LicenseParam initLicenseParam(LicenseVerifyParam param) {
        Preferences preferences = Preferences.userNodeForPackage(LicenseVerify.class);

        CipherParam cipherParam = new DefaultCipherParam(param.getStorePass());

        KeyStoreParam publicStoreParam = new CustomKeyStoreParam(LicenseVerify.class
                , param.getPublicKeysStorePath()
                , param.getPublicAlias()
                , param.getStorePass()
                , null);

        return new DefaultLicenseParam(param.getSubject()
                , preferences
                , publicStoreParam
                , cipherParam);
    }

}